package com.example.understandvideo.service;

import com.example.understandvideo.mapper.AnalysisTaskDao;
import com.example.understandvideo.mapper.AsrTaskDao;
import com.example.understandvideo.mapper.SmartTaskDao;
import com.example.understandvideo.pojo.AnalysisTask;
import com.example.understandvideo.pojo.AsrTask;
import com.example.understandvideo.pojo.SmartTask;
import com.example.understandvideo.tool.VideoFrameExtractor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PreDestroy;
import javax.annotation.Resource;
import java.io.File;
import java.time.LocalDate;
import java.util.Date;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

@Slf4j
@Component
public class VoiceProcessor {
    private final BlockingQueue<AsrTask> queue = new LinkedBlockingQueue<>(100);
    private volatile boolean running = true;
    private final int THREAD_COUNT = 10;
    @Resource
    private DemoService demoService;
    @Resource
    private AsrTaskDao asrTaskDao;
    @Resource
    private CommonService commonService;
    @Resource
    private LogService logService;

    /**
     * 创建线程池，核心10，最大核心30，存活5秒，队列存储2000，拒绝策略直接抛出异常
     */
    private final ThreadPoolExecutor threadPool = new ThreadPoolExecutor(THREAD_COUNT, 30,
            5, TimeUnit.SECONDS, new LinkedBlockingQueue<>(100),
            new ThreadPoolExecutor.CallerRunsPolicy());

    public VoiceProcessor() {
        for (int i = 0; i < THREAD_COUNT; i++) {
            threadPool.execute(new VoiceProcessor.ResultWorker());
        }
    }
    public void putByAnalysis(String filepath,Long id) {
        try {
            File file = new File(filepath);
            String name = file.getName().substring(0, file.getName().length() - 4);
            String targetDirPath = commonService.getWorkSpace() + "voice" + File.separator + LocalDate.now() + File.separator;
            String targetVoicePath = targetDirPath + name + "-output.mp3";
            File targetPicDir = new File(targetDirPath);
            if (!targetPicDir.exists()) {
                targetPicDir.mkdirs();
            }
            AsrTask task = new AsrTask();
            task.setFilepath(targetVoicePath);
            task.setStatus(0);
            task.setPid(id);
            //0代表smartTask,1代表analysisTask
            task.setPTable(1);
            asrTaskDao.insert(task);
            try {
                // 实例化工具类，传入FFmpeg的路径
                VideoFrameExtractor extractor = new VideoFrameExtractor(commonService.getFfmpegExcFileName());
                // 调用方法抽取音频
                extractor.extractVoice(filepath, targetVoicePath);
            } catch (Exception e) {
                task.setStatus(2);
                asrTaskDao.updateStatus(task);
                logService.logAsrMsg(task.getId(),"抽取音频失败+\n"+e.getMessage());
                e.printStackTrace();
            }
            this.queue.put(task);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }


    @PreDestroy
    public void stop() throws InterruptedException {
        this.running = false;
        //ExecutorUtil.shutdown(threadPool);
    }

    private class ResultWorker implements Runnable {
        @Override
        public void run() {
            try {
                while (running) {
                    AsrTask model = queue.take();
                    try {
                        String content = demoService.audioUnderstand(model.getFilepath());
                        model.setContent(content);
                        model.setStatus(1);
                        asrTaskDao.updateByPrimaryKey(model);
                    }catch (Exception e){
                        model.setStatus(2);
                        asrTaskDao.updateStatus(model);
                        logService.logAsrMsg(model.getId(),"语言识别调用引擎失败+\n"+e.getMessage());
                        e.printStackTrace();
                    }
                }
            } catch (Exception ex) {
                log.error("[VoiceProcessor] run error={}", ex.getMessage());
            }
        }
    }
}
